/**
 *
 */
package anysware.gwt.client.ui;

import anysware.gwt.client.rest.CallbackEvent;
import anysware.gwt.client.rest.CallbackListener;
import anysware.gwt.client.rest.RestRequestBuilder;
import anysware.gwt.client.util.PageUtils;
import anysware.gwt.client.util.QueryBuilder;

import com.google.gwt.core.client.GWT;
import com.google.gwt.http.client.Response;
import com.google.gwt.http.client.URL;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONParser;
import com.google.gwt.json.client.JSONString;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;

public class SourceEditor extends Composite implements ClickListener {
	private final Button	         cancel	= new Button("Cancel", this);
	private boolean	                 empty	= true;
	private TextBox	                 name;
	private final SimplePanel	     outer	= new SimplePanel();
	private TextBox	                 path;
	private final Button	         save	= new Button("Save", this);
	private JSONObject	             source;
	/**
	 *
	 */
	private final SourceEditorDialog	sourceEditor;
	private ListBox	                 type;

	public SourceEditor(final SourceEditorDialog sourceEditorDialog) {
		super();
		sourceEditor = sourceEditorDialog;
		initWidget(outer);
		setStyleName("source-editor");
	}

	public void addNew() {
		if (empty) {
			createFields();
		}
		final JSONObject obj = new JSONObject();
		final JSONObject pathObj = new JSONObject();
		pathObj.put("type", new JSONString("java.net.URL"));
		obj.put("path", pathObj);
		setSource(obj);
	}

	public void onClick(final Widget sender) {

		if (sender == save) {
			final QueryBuilder qb = new QueryBuilder();
			qb.add("name", name.getText()).add("type",
			        type.getValue(type.getSelectedIndex())).add("path",
			        path.getText());
			RestRequestBuilder builder = null;
			if (source.get("id") == null) {
				builder = RestRequestBuilder.createBuilder("POST", PageUtils
				        .getProperty("endpoint.source"));
			} else {
				builder = RestRequestBuilder.createBuilder("PUT", PageUtils
				        .getProperty("endpoint.source")
				        + "/" + URL.encodeComponent(name.getText()));
				qb.add("id", ""
				        + (long) source.get("id").isNumber().doubleValue());
			}
			builder.setHeader("accept", "application/json");
			builder.setHeader("content-type",
			        "application/x-www-form-urlencoded");
			builder.sendRequest(qb.build(), new CallbackListener() {
				public void handle(final CallbackEvent event) {
					GWT.log("Handle send completed:" + event.getReason(), null);
					if (event.getReason().equals(CallbackEvent.Reason.SUCCESS)) {
						final Response response = event.getResponse();
						GWT.log("Response: " + response.getStatusCode() + ":"
						        + response.getStatusText(), null);
						if (response.getStatusCode() == 201) {

							// created
							final JSONObject item = JSONParser.parse(
							        response.getText()).isObject();
							GWT.log("New item added: " + item, null);
							source = item;
							sourceEditor.addItem(item);
						} else if (response.getStatusCode() == 200) {
							// saved
							source.put("name", new JSONString(name.getText()));
							source.put("type", new JSONString(type
							        .getValue(type.getSelectedIndex())));
							source.get("path").isObject().put("$",
							        new JSONString(path.getText()));
						}
					}
				}
			});
		} else {
			setSource(source);
		}
	}

	public void setSource(final JSONObject source) {
		if (empty) {
			createFields();
		}
		this.source = source;
		if (source.get("name") != null) {
			name.setText(source.get("name").isString().stringValue());
		} else {
			name.setText(null);
		}
		if (source.get("path").isObject().get("$") != null) {
			path.setText(source.get("path").isObject().get("$").isString()
			        .stringValue());
		} else {
			path.setText(null);
		}
		if (source.get("type") != null) {
			final String typeValue = source.get("type").isString()
			        .stringValue();
			for (int i = 0; i < type.getItemCount(); i++) {
				if (typeValue.equals(type.getValue(i))) {
					type.setSelectedIndex(i);
				}
			}
		} else {
			type.setSelectedIndex(0);
		}
	}

	private void createFields() {
		final FlexTable inner = new FlexTable();
		name = new TextBox();
		type = new ListBox();
		type.addItem("");
		type.addItem("File", "anysware:source:file");
		path = new TextBox();
		inner.setHTML(0, 0, "Name");
		inner.setWidget(0, 1, name);
		inner.setHTML(1, 0, "Type");
		inner.setWidget(1, 1, type);
		inner.setHTML(2, 0, "Path");
		inner.setWidget(2, 1, path);
		inner.setWidget(3, 0, save);
		inner.setWidget(3, 1, cancel);
		outer.setWidget(inner);
		empty = false;
	}
}